package ace.cmp.spring.data.jdbc.querydsl.core.repository.handler.impl;

import ace.cmp.spring.data.jdbc.querydsl.core.QuerydslJdbcConstants;
import ace.cmp.spring.data.jdbc.querydsl.core.model.PropertyRelation;
import ace.cmp.spring.data.jdbc.querydsl.core.repository.handler.QuerydslVersionGenerator;
import com.querydsl.core.types.Expression;
import com.querydsl.core.types.dsl.Expressions;
import java.sql.Timestamp;
import java.time.Instant;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.UUID;

/**
 * @author caspar
 * @date 2024/6/26 16:03 创建版本号
 */
public class QuerydslVersionGeneratorImpl implements QuerydslVersionGenerator {

  @Override
  public Object generateNewValue(Object entity, PropertyRelation propertyRelation) {
    String typeName = propertyRelation.getField().getGenericType().getTypeName();
    if (String.class.getTypeName().equals(typeName)) {
      return UUID.randomUUID().toString();
    } else if (Long.class.getTypeName().equals(typeName)) {
      return Long.valueOf(QuerydslJdbcConstants.INIT_VERSION_LONG);
    } else if (Integer.class.getTypeName().equals(typeName)) {
      return Integer.valueOf(QuerydslJdbcConstants.INIT_VERSION_INT);
    } else if (LocalDateTime.class.getTypeName().equals(typeName)) {
      return LocalDateTime.now();
    } else if (Date.class.getTypeName().equals(typeName)) {
      return new Date();
    } else if (Timestamp.class.getTypeName().equals(typeName)) {
      return Timestamp.valueOf(LocalDateTime.now());
    } else {
      return null;
    }
  }

  @Override
  public Expression<?> generateNewExpression(
      Object entity, Object value, PropertyRelation propertyRelation) {
    String typeName = propertyRelation.getField().getGenericType().getTypeName();
    if (String.class.getTypeName().equals(typeName)) {
      return Expressions.asString(UUID.randomUUID().toString());
    } else if (Long.class.getTypeName().equals(typeName)) {
      return Expressions.asNumber((Expression) propertyRelation.getExpression()).add(1);
    } else if (Integer.class.getTypeName().equals(typeName)) {
      return Expressions.asNumber((Expression) propertyRelation.getExpression()).add(1);
    } else if (LocalDateTime.class.getTypeName().equals(typeName)) {
      return Expressions.asDateTime(LocalDateTime.now());
    } else if (Date.class.getTypeName().equals(typeName)) {
      return Expressions.asDateTime(Date.from(Instant.now()));
    } else if (Timestamp.class.getTypeName().equals(typeName)) {
      return Expressions.asSimple(LocalDateTime.now());
    } else {
      return null;
    }
  }
}
